1. Map Area

1.1. The map

I have chosed the map sector of the dynamically developing area in the UAE. For displaying the area I have used the package “ggmap” and the coordinates of this area in dubai_abu-dhabi.osm.

dubai_gmap <- get_map(location=c(lon = 55.2708, lat = 25.2048), 
                      source = "google", maptype = "hybrid", zoom = 8)
ggmap(dubai_gmap, extent = "normal")

osmmap <- get_map(location = c(53.5800,23.7350,56.8870,26.5390), source = "osm")
ggmap(osmmap, extent = "normal")

bounds: minlat=“23.7350” minlon=“53.5800” maxlat=“26.5390” maxlon=“56.8870”

The reader can see some examples of use the ggmap package besides just displaying the maps.

gc01 <- geocode("Jumerah Gardens", output = "more")
formattable(data.frame(gc01))
gc03 <- geocode("Dubai International Airport", output = "more")
formattable(data.frame(gc03))
formattable(data.frame(mapdist("dubai", "abu-dhabi")))
formattable(data.frame(mapdist("Jumerah Gardens", "Dubai International Airport")))
var_ways <- route('The Dubai Moll', 'Business Bay', alternatives = TRUE)
formattable(head(data.frame(var_ways)))
ggplot(data = var_ways) + coord_map() +
  geom_leg(aes(x = startLon, xend = endLon, y = startLat, yend = endLat, color = route))

qmap(location=c(55.2820, 25.1900), zoom = 15, maptype = 'roadmap', 
     base_layer = ggplot(aes(x = startLon, y = startLat), data = var_ways)) +
  geom_leg(aes(x = startLon, xend = endLon, 
               y = startLat, yend = endLat, color = route), 
           alpha = 0.5, size = 2, data = var_ways) +
  labs(x = 'Longitude', y = 'Latitude', colour = 'Route') +
  facet_wrap(~ route, ncol = 3) + theme(legend.position = 'top')

way_map <- get_map(location = c(55.2820, 25.1900), 
                   source = "google", zoom = 15, maptype = "hybrid")
ggmap(way_map) + geom_leg(data = var_ways, 
                          aes(x = startLon, xend = endLon, 
                              y = startLat, yend = endLat, color = route), 
                          alpha = 0.7, size = 2)

1.2 Extract with osmar R

There are several ways to extract geodata. One of them is to do this with this R code cells.

This set of commands allows us to upload the data using the coordinates.

src <- osmsource_api()
bigbox <- center_bbox(55.2708, 25.2048, 6000, 6000)
bdubai <- get_osm(bigbox, source = src)
str(bdubai)
List of 3
 $ nodes    :List of 2
  ..$ attrs:'data.frame':   47528 obs. of  9 variables:
  .. ..$ id       : num [1:47528] 30593914 30593915 31473923 31474006 31474005 ...
  .. ..$ visible  : Factor w/ 1 level "true": 1 1 1 1 1 1 1 1 1 1 ...
  .. ..$ timestamp: POSIXlt[1:47528], format: "2016-08-19 09:40:14" "2010-12-14 12:40:14" "2010-12-02 12:23:45" ...
  .. ..$ version  : num [1:47528] 19 4 2 5 5 5 2 5 2 2 ...
  .. ..$ changeset: num [1:47528] 41552017 6657884 6514101 7313392 7313392 ...
  .. ..$ user     : Factor w/ 203 levels "08xavstj","12Katniss",..: 60 172 172 182 182 182 172 172 172 77 ...
  .. ..$ uid      : Factor w/ 203 levels "1069176","10927",..: 60 2 2 41 41 41 2 2 2 81 ...
  .. ..$ lat      : num [1:47528] 25.2 25.2 25.2 25.2 25.2 ...
  .. ..$ lon      : num [1:47528] 55.3 55.3 55.3 55.3 55.3 ...
  ..$ tags :'data.frame':   1956 obs. of  3 variables:
  .. ..$ id: num [1:1956] 9.11e+07 9.50e+07 9.50e+07 2.60e+08 2.81e+08 ...
  .. ..$ k : Factor w/ 104 levels "access","addr:city",..: 36 36 72 12 86 50 41 50 51 53 ...
  .. ..$ v : Factor w/ 738 levels "-1","+18006437560",..: 659 486 63 349 453 469 295 150 720 150 ...
  ..- attr(*, "class")= chr [1:3] "nodes" "osmar_element" "list"
 $ ways     :List of 3
  ..$ attrs:'data.frame':   6547 obs. of  7 variables:
  .. ..$ id       : num [1:6547] 4.86e+06 1.04e+08 1.04e+08 1.04e+08 1.06e+07 ...
  .. ..$ visible  : Factor w/ 1 level "true": 1 1 1 1 1 1 1 1 1 1 ...
  .. ..$ timestamp: POSIXlt[1:6547], format: "2014-05-05 11:47:38" "2011-03-12 17:37:11" "2011-03-12 17:37:11" ...
  .. ..$ version  : num [1:6547] 9 1 1 2 10 7 5 8 6 4 ...
  .. ..$ changeset: num [1:6547] 22145147 7535955 7535955 35985485 16483397 ...
  .. ..$ user     : Factor w/ 125 levels "12Katniss","13 digits",..: 29 111 111 5 28 111 28 78 28 104 ...
  .. ..$ uid      : Factor w/ 125 levels "1069176","10927",..: 123 30 30 66 39 30 39 40 39 2 ...
  ..$ tags :'data.frame':   10072 obs. of  3 variables:
  .. ..$ id: num [1:10072] 4.86e+06 4.86e+06 4.86e+06 1.04e+08 1.04e+08 ...
  .. ..$ k : Factor w/ 135 levels "access","access:note",..: 58 74 96 58 58 25 79 58 68 74 ...
  .. ..$ v : Factor w/ 858 levels "-1","-2","+971 4 323 0000",..: 625 257 814 703 703 814 798 624 1 26 ...
  ..$ refs :'data.frame':   56522 obs. of  2 variables:
  .. ..$ id : num [1:56522] 4.86e+06 4.86e+06 4.86e+06 4.86e+06 1.04e+08 ...
  .. ..$ ref: num [1:56522] 9.10e+07 2.84e+09 2.84e+09 9.10e+07 9.39e+07 ...
  ..- attr(*, "class")= chr [1:3] "ways" "osmar_element" "list"
 $ relations:List of 3
  ..$ attrs:'data.frame':   52 obs. of  7 variables:
  .. ..$ id       : num [1:52] 2757400 2757402 2757403 1320963 1320964 ...
  .. ..$ visible  : Factor w/ 1 level "true": 1 1 1 1 1 1 1 1 1 1 ...
  .. ..$ timestamp: POSIXlt[1:52], format: "2013-02-13 16:02:48" "2013-02-13 16:02:48" "2013-02-13 16:02:48" ...
  .. ..$ version  : num [1:52] 1 1 1 1 1 2 1 1 1 1 ...
  .. ..$ changeset: num [1:52] 15019545 15019545 15019545 6657884 6657884 ...
  .. ..$ user     : Factor w/ 16 levels "4b696d","Alex111X",..: 15 15 15 13 13 15 15 10 10 10 ...
  .. ..$ uid      : Factor w/ 16 levels "10927","114220",..: 5 5 5 1 1 5 5 6 6 6 ...
  ..$ tags :'data.frame':   287 obs. of  3 variables:
  .. ..$ id: num [1:287] 2757400 2757400 2757402 2757402 2757403 ...
  .. ..$ k : Factor w/ 184 levels "alt_name:af",..: 175 180 175 180 175 180 175 180 175 180 ...
  .. ..$ v : Factor w/ 167 levels "-1","#CC0000",..: 83 102 83 102 83 102 83 102 83 102 ...
  ..$ refs :'data.frame':   1523 obs. of  4 variables:
  .. ..$ id  : num [1:1523] 2757400 2757400 2757400 2757402 2757402 ...
  .. ..$ type: Factor w/ 2 levels "node","way": 2 2 1 2 2 1 2 2 1 2 ...
  .. ..$ ref : num [1:1523] 2.05e+08 2.05e+08 2.15e+09 2.05e+08 2.05e+08 ...
  .. ..$ role: Factor w/ 11 levels "","cable","from",..: 3 10 11 3 10 11 3 10 11 3 ...
  ..- attr(*, "class")= chr [1:3] "relations" "osmar_element" "list"
 - attr(*, "class")= chr [1:2] "osmar" "list"

Node tags:

node_tags <- sort(unique(bdubai$nodes$tags$k))
print(node_tags)
  [1] access                          addr:city                       addr:country                   
  [4] addr:flats                      addr:housename                  addr:housenumber               
  [7] addr:place                      addr:postcode                   addr:street                    
 [10] addr:subdistrict                aeroway                         amenity                        
 [13] barrier                         bench                           bicycle                        
 [16] building                        bus                             capacity                       
 [19] construction                    contact:instagram               country                        
 [22] covered                         crossing                        cuisine                        
 [25] delivery                        description                     diplomatic                     
 [28] direction                       drive_in                        drive_through                  
 [31] ele                             email                           entrance                       
 [34] fee                             foot                            highway                        
 [37] horse                           indoor_seating                  internet_access                
 [40] internet_access:fee             is_in                           layer                          
 [43] leisure                         level                           levels                         
 [46] lit                             man_made                        maxspeed                       
 [49] motor_vehicle                   name                            name:ar                        
 [52] name:de                         name:en                         name:fr                        
 [55] name:ko                         name:pl                         name:ru                        
 [58] natural                         note                            office                         
 [61] opening_hours                   operator                        outdoor_seating                
 [64] parking                         payment:bitcoin                 phone                          
 [67] place                           platforms                       power                          
 [70] public_transport                railway                         ref                            
 [73] religion                        seamark:beacon_lateral:category seamark:beacon_lateral:colour  
 [76] seamark:beacon_lateral:system   seamark:information             seamark:light:character        
 [79] seamark:light:colour            seamark:light:group             seamark:light:period           
 [82] seamark:light:reference         seamark:name                    seamark:type                   
 [85] shelter                         shop                            shower                         
 [88] smoking                         source                          sport                          
 [91] station                         subway                          supervised                     
 [94] surface                         surveillance                    surveillance:type              
 [97] surveillance:zone               takeaway                        tourism                        
[100] traffic_calming                 type                            website                        
[103] wheelchair                      wikipedia                      
104 Levels: access addr:city addr:country addr:flats addr:housename addr:housenumber ... wikipedia

Way tags:

way_tags <- sort(unique(bdubai$ways$tags$k))
print(way_tags)
  [1] access                   access:note              addr:city                addr:country            
  [5] addr:housename           addr:housenumber         addr:postcode            addr:street             
  [9] addr:suburb              admin_level              aerialway                aeroway                 
 [13] alt_name                 alt_name:hu              alt_name2                alt_old_name:hu         
 [17] amenity                  area                     atm                      barrier                 
 [21] bicycle                  boundary                 bridge                   bridge:structure        
 [25] building                 building:height          building:levels          building:material       
 [29] building:part            bus                      cables                   capacity                
 [33] construction             contact:email            contact:facebook         contact:fax             
 [37] contact:google_plus      contact:instagram        contact:phone            contact:twitter         
 [41] contact:website          covered                  created_by               crossing                
 [45] cutting                  description              destination              destination:lanes       
 [49] ele                      email                    escalator                fee                     
 [53] fence_type               foot                     footway                  frequency               
 [57] height                   highway                  highway_1                horse                   
 [61] hotel                    indoor                   internet_access          is_in                   
 [65] junction                 landuse                  lanes                    layer                   
 [69] leisure                  level                    lit                      loc_name                
 [73] man_made                 maxspeed                 maxspeed:hgv             maxstay                 
 [77] mooring                  motor_vehicle            name                     name:ar                 
 [81] name:en                  name:et                  name:he                  name:hu                 
 [85] name:ko                  name:loc                 name:ru                  name:sl                 
 [89] name:uk                  name:zh                  natural                  note                    
 [93] office                   old_name                 old_name:hu              oneway                  
 [97] opening_hours            operator                 park_ride                parking                 
[101] phone                    place                    power                    public_transport:version
[105] railway                  ref                      religion                 roof:material           
[109] roof:shape               room                     rooms                    service                 
[113] shop                     sloped_curb              smoking                  source                  
[117] sport                    stars                    start_date               surface                 
[121] tactile_paving           toll                     tourism                  tracktype               
[125] tunnel                   turn:lanes               voltage                  water                   
[129] waterway                 website                  wheelchair               wheelchair:description  
[133] wikidata                 wikipedia                wires                   
135 Levels: access access:note addr:city addr:country addr:housename addr:housenumber ... wires

Users:

users <- sort(unique(bdubai$nodes$attrs$user))
print(head(users, 12))
 [1] 08xavstj                12Katniss               13 digits               Abdulaziz AlSweda      
 [5] acltpe                  Ahamed Zulfan           ahmed abdo edries nasur Ahmed Arafa40          
 [9] Akos Vancza             Alex111X                alwasam6                amanza                 
203 Levels: 08xavstj 12Katniss 13 digits Abdulaziz AlSweda acltpe ... ‫نبيل الغسيني‬‎

1.3 Plotting with osmar R

plot(bdubai)

ts <- find(bdubai, node(tags(v == "traffic_signals")))
ts_dubai <- subset(bdubai, node_ids = ts)
bs <- find(bdubai, node(tags(v %agrep% "busstop")))
bs_dubai <- subset(bdubai, node_ids = bs)
hw <- find(bdubai, way(tags(k == "highway")))
hw <- find_down(bdubai, way(hw))
hw_dubai <- subset(bdubai, ids = hw)
tu <- find(bdubai, way(tags(k == "tunnel")))
tu <- find_down(bdubai, way(tu))
tu_dubai <- subset(bdubai, ids = tu)
plot_ways(hw_dubai, col = "steelblue")
plot_ways(tu_dubai, add = TRUE, col = "magenta")
plot_nodes(ts_dubai, add = TRUE, col = "red")
plot_nodes(bs_dubai, add = TRUE, col = "blue")

bg <- find(bdubai, way(tags(k == "building")))
bg <- find_down(bdubai, way(bg))
bg_dubai <- subset(bdubai, ids = bg)
bg_poly <- as_sp(bg_dubai, "polygons")
spplot(bg_poly, col.regions=brewer.pal(12, "Set3"), c("version"))

# bus <- find(bdubai, relation(tags(v == "bus")))
# bus_dubai <- lapply(bus, function(i) { as_sp(get_osm(relation(i), full = TRUE), "lines") })
bs_points <- as_sp(bs_dubai, "points")
hw_line <- as_sp(hw_dubai, "lines")
# for ( i in seq(along = bus_dubai) ) { plot(bus[[i]], add = TRUE, col = "blue") }
plot(bg_poly, col = "lightsteelblue")
plot(hw_line, add = TRUE, col = "blue")
plot(bs_points, add = TRUE, col = "red")

1.4. Extract from OpenStreetMaps.org.

Another possible way is extracting data files in many different formats from the website: https://mapzen.com/data/metro-extracts/metro/dubai_abu-dhabi/ . The files dubai_abu-dhabi.osm, dubai_abu-dhabi_buildings.geojson, etc. were downloaded. The data from the format osm of the file were extracted in formats csv and json using specially designed functions in the programming language python.

Size of the downloaded osm, json and csv file.

print(file.size("/Users/olgabelitskaya/large-repo/dubai_abu-dhabi.osm"))
[1] 394382598
print(file.size("/Users/olgabelitskaya/large-repo/dubai_abu-dhabi.osm.json"))
[1] 458155339
print(file.size("/Users/olgabelitskaya/large-repo/nodes.csv"))
[1] 154228820
print(file.size("/Users/olgabelitskaya/large-repo/nodes_tags.csv"))
[1] 3912302
print(file.size("/Users/olgabelitskaya/large-repo/ways.csv"))
[1] 13797779
print(file.size("/Users/olgabelitskaya/large-repo/ways_tags.csv"))
[1] 13383027
print(file.size("/Users/olgabelitskaya/large-repo/ways_nodes.csv"))
[1] 55135540

2. CSV & SQL

The displayed lines of code represent the process of recording information of the CSV files to the SQL database.

sqlite <- dbDriver("SQLite")
dubai_abu_dhabi <- dbConnect(sqlite,"dubai_abu_dhabi.sqlite3")
nodes <- read.csv('/Users/olgabelitskaya/large-repo/nodes.csv')
nodes_tags <- read.csv('/Users/olgabelitskaya/large-repo/nodes_tags.csv')
ways <- read.csv('/Users/olgabelitskaya/large-repo/ways.csv')
ways_tags <- read.csv('/Users/olgabelitskaya/large-repo/ways_tags.csv')
ways_nodes <- read.csv('/Users/olgabelitskaya/large-repo/ways_nodes.csv')
dbWriteTable(conn = dubai_abu_dhabi, name = 'nodes', value = nodes, row.names = FALSE)
dbWriteTable(conn = dubai_abu_dhabi, name = 'nodes_tags', value = nodes_tags, row.names = FALSE)
dbWriteTable(conn = dubai_abu_dhabi, name = 'ways', value = ways, row.names = FALSE)
dbWriteTable(conn = dubai_abu_dhabi, name = 'ways_tags', value = ways_tags, row.names = FALSE)
dbWriteTable(conn = dubai_abu_dhabi, name = 'ways_nodes', value = ways_nodes, row.names = FALSE)

With the help of simple manipulations in the database, the user can perform a selection of interesting information.

The examples of nodes and ways:

formattable(sqldf("select * from nodes limit 3", dbname = "dubai_abu_dhabi"))
formattable(sqldf("select * from ways limit 3", dbname = "dubai_abu_dhabi"))

We can find the number of nodes and ways as well.

formattable(sqldf("SELECT COUNT(*) FROM nodes;"))
formattable(sqldf("SELECT COUNT(*) FROM ways;"))

The number of users:

formattable(sqldf("SELECT COUNT(DISTINCT(e.uid)) FROM \
          (SELECT uid FROM nodes UNION ALL SELECT uid FROM ways) e;"))

The database allows to evaluate the contribution of each individual user in map editing.

Let us list the three most active editors of this map section:

formattable(sqldf("SELECT e.user, COUNT(*) as num \
           FROM (SELECT user FROM nodes UNION ALL SELECT user FROM ways) e \
           GROUP BY e.user \
           ORDER BY num DESC \
           LIMIT 3;"))

A list of the 3 most common types of places:

formattable(sqldf("SELECT value, COUNT(*) as num \
            FROM nodes_tags \
            WHERE key='place' \
            GROUP BY value \
            ORDER BY num DESC \
            LIMIT 3;"))

A list of the 10 most common types of buildings:

formattable(sqldf("SELECT value, COUNT(*) as num \
            FROM nodes_tags \
            WHERE key='building' \
            GROUP BY value \
            ORDER BY num DESC \
            LIMIT 10;"))

A list of the 20 most common streets:

formattable(sqldf("SELECT value, COUNT(*) as num \
            FROM nodes_tags \
           WHERE key='street' \
           GROUP BY value \
           ORDER BY num DESC \
           LIMIT 20;"))
dbDisconnect(dubai_abu_dhabi)
[1] TRUE

3. JSON & MongoDB

With very similar manipulations we can import the data from JSON files into MongoDB.

Start with running ‘mongod’ from the terminal, end with ‘Ctrl+C’.

m <- mongo("openstreetmap", verbose = FALSE)
# stream_in(file("dubai_abu-dhabi.osm.json"), handler = function(df){m$insert(df)})

The number of documents:

m$count()
[1] 2124505

The three most active editors of this map section:

top_users <- m$aggregate('[
{ "$group" : { "_id" : "$created.user", "count" : { "$sum" : 1} } }, 
{ "$sort" : { "count" : -1} }, { "$limit" : 3 } 
]')
formattable(top_users)

The number of users with one note and the list of 10 users with only one note:

number_oonu <- m$aggregate('[
{ "$group" : { "_id" : "$created.user", "count" : { "$sum" : 1} } }, 
{ "$sort" : { "count" : 1} }, { "$limit" : 10 } 
]')
formattable(number_oonu)
ten_oonu <- m$aggregate('[
{ "$group" : { "_id" : "$created.user", "count" : { "$sum" : 1} } }, 
{ "$sort" : { "count" : 1} }, { "$limit" : 10 } 
]')
formattable(ten_oonu)

A list of 3 most common places:

places <- m$aggregate('[
{ "$match" : { "address.place" : { "$exists" : 1} } }, 
{ "$group" : { "_id" : "$address.place", "count" : { "$sum" : 1} } },  
{ "$sort" : { "count" : -1}}, {"$limit":3}
]')
formattable(places)

A list of 10 most common types of buildings:

buildings <- m$aggregate('[
{ "$match": { "building": { "$exists": 1}}}, 
{ "$group": { "_id": "$building", "count": { "$sum": 1}}}, 
{ "$sort": { "count": -1}}, {"$limit": 10}
]')
formattable(buildings)

A list of 10 most common facilities:

facilities <- m$aggregate('[
{ "$match": { "amenity": { "$exists": 1}}}, 
{ "$group": { "_id": "$amenity", "count": { "$sum": 1}}},
{ "$sort": { "count": -1}}, { "$limit": 10}
]')
formattable(facilities)

A list of 3 most common zipcodes:

postcodes <- m$aggregate('[ 
{ "$match" : { "address.postcode" : { "$exists" : 1} } }, 
{ "$group" : { "_id" : "$address.postcode", "count" : { "$sum" : 1} } },  
{ "$sort" : { "count" : -1}}, {"$limit": 3}
]')
formattable(postcodes)

Counting zipcodes with one document:

postcodes_od <- m$aggregate('[ 
{ "$group" : {"_id" : "$address.postcode", "count" : { "$sum" : 1} } },
{ "$group" : {"_id" : "$count", "count": { "$sum" : 1} } },
{ "$sort" : {"_id" : 1} }, { "$limit" : 1} 
]')
formattable(postcodes_od)

Examples of statistics indicators for this dataset:

m$info()$stats$ns
[1] "test.openstreetmap"
m$info()$stats$size
[1] 502488587
m$info()$stats$avgObjSize
[1] 236
m$info()$stats$storageSize
[1] 155140096

4. Problems and errors

4.1

One of the main problems of public maps - no duplication of all place names in other languages. If it were possible to automate the translation process by increasing a common database of map names in many languages, it would save users from many difficulties and mistakes.

4.2

The next problem - the presence of a large number of databases (including mapping) on the same map objects. Some intergraph procedures of already available data would relieve a lot of people from unnecessary work, save time and effort.

4.3

Obviously, the information about the number of buildings and their purpose is incomplete. Completeness of public maps can be increased by bringing in the process of mapping new users. For this goal enter the information should be as simple as possible: for example, a choice of the available options with automatic filling many fields for linked options (for example, linking the name of the street and the administrative area in which it is located).

4.4

There are a number of mistakes and typos as in every public data. For correction them well-known methods can be proposed: automatic comparison with existing data and verification for new data by other users.

4.5

The lack of a uniform postal code system in this concrete dataset complicates their identification and verification.

5. Data Overview

5.1 Description of the data structure:

  1. nodes - points in space with basic characteristics (lat, long, id, tags);

  2. ways - defining linear features and area boundaries (an ordered list of nodes);

  3. relations - tags and also an ordered list of nodes, ways and/or relations as members which is used to define logical or geographic relationships between other elements.

5.2 Indicators.

  1. Size of the .osm file: 394,4 MB.
  2. Size of the .osm sample file : 3,9 MB.
  3. Nodes: 1890178.
  4. Ways: 234327.
  5. Relations: 2820.
  6. Tags: 503027.
  7. Users: 1895.

5.3 SQL & MongoDB

With the help of a specific set of commands we can perform a statistical description of the data collections and the database.

6. Conclusion

I think this project is educational for me. I believe that one of the main tasks in this case was to study the methods of extraction and researching of map data in open access. For example, I used a systematic sample of elements from the original .osm file for trying functions of processing before applying them to the whole dataset. As a result I have some new useful skills in parsing, processing, storing, aggregating and applying the data.

In the research I have read through quite a lot of projects of other students on this topic. After my own research and review the results of other authors I have formed a definite opinion about the ideas in OpenStreetMap.

This website can be viewed as a testing ground of interaction of a large number of people (ncluding non-professionals) to create a unified information space. The prospects of such cooperation can not be overemphasized. The success of the project will allow to implement the ambitious plans in the field of available information technologies, the creation of virtual reality and many other areas.

Increasing of the number of users leads to many positive effects in this kind of projects:

  1. a rapid improvement in the accuracy, completeness and timeliness of information;

  2. approximation of the information space to the reality , the objectivity of the data evaluation;

  3. reduce the effort for data cleansing on erroneous details.

Ideas for improving the project OpenStreetMap are simple and natural.

Increasing the number of users can be achieved by additional options like marks of the rating evaluation (eg, the best restaurant or the most convenient parking).

The popularity of the project may be more due to the temporary pop-up messages of users (placement is not more than 1-3 hours) with actual information about the geographic location (eg, the presence of traffic jams).

LS0tCnRpdGxlOiAiUDM6IE9wZW5TdHJlZXRNYXAgRGF0YSBDYXNlIFN0dWR5IgphdXRob3I6ICJPbGdhIEJlbGl0c2theWEiCmRhdGU6ICIyMDE2LTExLTI2IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KHBsb3RseSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdnbWFwKQpsaWJyYXJ5KGZvcm1hdHRhYmxlKQpsaWJyYXJ5KG9zbWFyKQpsaWJyYXJ5KFJDb2xvckJyZXdlcikKbGlicmFyeShSU1FMaXRlKQpsaWJyYXJ5KHNxbGRmKQpsaWJyYXJ5KG1vbmdvbGl0ZSkKbGlicmFyeShqc29ubGl0ZSkKYGBgCiMjIyAxLiBNYXAgQXJlYQoKIyMjIyAxLjEuIFRoZSBtYXAKSSBoYXZlIGNob3NlZCB0aGUgbWFwIHNlY3RvciBvZiB0aGUgZHluYW1pY2FsbHkgZGV2ZWxvcGluZyBhcmVhIGluIHRoZSBVQUUuCkZvciBkaXNwbGF5aW5nIHRoZSBhcmVhIEkgaGF2ZSB1c2VkIHRoZSBwYWNrYWdlICJnZ21hcCIgYW5kIHRoZSBjb29yZGluYXRlcyBvZiB0aGlzIGFyZWEgaW4gZHViYWlfYWJ1LWRoYWJpLm9zbS4KYGBge3IgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTEwLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpkdWJhaV9nbWFwIDwtIGdldF9tYXAobG9jYXRpb249Yyhsb24gPSA1NS4yNzA4LCBsYXQgPSAyNS4yMDQ4KSwgCiAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UgPSAiZ29vZ2xlIiwgbWFwdHlwZSA9ICJoeWJyaWQiLCB6b29tID0gOCkKZ2dtYXAoZHViYWlfZ21hcCwgZXh0ZW50ID0gIm5vcm1hbCIpCmBgYApgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD02LCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpvc21tYXAgPC0gZ2V0X21hcChsb2NhdGlvbiA9IGMoNTMuNTgwMCwyMy43MzUwLDU2Ljg4NzAsMjYuNTM5MCksIHNvdXJjZSA9ICJvc20iKQpnZ21hcChvc21tYXAsIGV4dGVudCA9ICJub3JtYWwiKQpgYGAKIyMjIyBib3VuZHM6IG1pbmxhdD0iMjMuNzM1MCIgbWlubG9uPSI1My41ODAwIiBtYXhsYXQ9IjI2LjUzOTAiIG1heGxvbj0iNTYuODg3MCIKClRoZSByZWFkZXIgY2FuIHNlZSBzb21lIGV4YW1wbGVzIG9mIHVzZSB0aGUgZ2dtYXAgcGFja2FnZSBiZXNpZGVzIGp1c3QgZGlzcGxheWluZyB0aGUgbWFwcy4KYGBge3IgbWVzc2FnZT1GQUxTRX0KZ2MwMSA8LSBnZW9jb2RlKCJKdW1lcmFoIEdhcmRlbnMiLCBvdXRwdXQgPSAibW9yZSIpCmZvcm1hdHRhYmxlKGRhdGEuZnJhbWUoZ2MwMSkpCmBgYApgYGB7ciBtZXNzYWdlPUZBTFNFfQpnYzAzIDwtIGdlb2NvZGUoIkR1YmFpIEludGVybmF0aW9uYWwgQWlycG9ydCIsIG91dHB1dCA9ICJtb3JlIikKZm9ybWF0dGFibGUoZGF0YS5mcmFtZShnYzAzKSkKYGBgCmBgYHtyIG1lc3NhZ2U9RkFMU0V9CmZvcm1hdHRhYmxlKGRhdGEuZnJhbWUobWFwZGlzdCgiZHViYWkiLCAiYWJ1LWRoYWJpIikpKQpgYGAKYGBge3IgbWVzc2FnZT1GQUxTRX0KZm9ybWF0dGFibGUoZGF0YS5mcmFtZShtYXBkaXN0KCJKdW1lcmFoIEdhcmRlbnMiLCAiRHViYWkgSW50ZXJuYXRpb25hbCBBaXJwb3J0IikpKQpgYGAKYGBge3IgbWVzc2FnZT1GQUxTRX0KdmFyX3dheXMgPC0gcm91dGUoJ1RoZSBEdWJhaSBNb2xsJywgJ0J1c2luZXNzIEJheScsIGFsdGVybmF0aXZlcyA9IFRSVUUpCmZvcm1hdHRhYmxlKGhlYWQoZGF0YS5mcmFtZSh2YXJfd2F5cykpKQpgYGAKYGBge3IgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NiwgbWVzc2FnZT1GQUxTRX0KZ2dwbG90KGRhdGEgPSB2YXJfd2F5cykgKyBjb29yZF9tYXAoKSArCiAgZ2VvbV9sZWcoYWVzKHggPSBzdGFydExvbiwgeGVuZCA9IGVuZExvbiwgeSA9IHN0YXJ0TGF0LCB5ZW5kID0gZW5kTGF0LCBjb2xvciA9IHJvdXRlKSkKYGBgCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD02LCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpxbWFwKGxvY2F0aW9uPWMoNTUuMjgyMCwgMjUuMTkwMCksIHpvb20gPSAxNSwgbWFwdHlwZSA9ICdyb2FkbWFwJywgCiAgICAgYmFzZV9sYXllciA9IGdncGxvdChhZXMoeCA9IHN0YXJ0TG9uLCB5ID0gc3RhcnRMYXQpLCBkYXRhID0gdmFyX3dheXMpKSArCiAgZ2VvbV9sZWcoYWVzKHggPSBzdGFydExvbiwgeGVuZCA9IGVuZExvbiwgCiAgICAgICAgICAgICAgIHkgPSBzdGFydExhdCwgeWVuZCA9IGVuZExhdCwgY29sb3IgPSByb3V0ZSksIAogICAgICAgICAgIGFscGhhID0gMC41LCBzaXplID0gMiwgZGF0YSA9IHZhcl93YXlzKSArCiAgbGFicyh4ID0gJ0xvbmdpdHVkZScsIHkgPSAnTGF0aXR1ZGUnLCBjb2xvdXIgPSAnUm91dGUnKSArCiAgZmFjZXRfd3JhcCh+IHJvdXRlLCBuY29sID0gMykgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAndG9wJykKYGBgCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD0xMCwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0Kd2F5X21hcCA8LSBnZXRfbWFwKGxvY2F0aW9uID0gYyg1NS4yODIwLCAyNS4xOTAwKSwgCiAgICAgICAgICAgICAgICAgICBzb3VyY2UgPSAiZ29vZ2xlIiwgem9vbSA9IDE1LCBtYXB0eXBlID0gImh5YnJpZCIpCmdnbWFwKHdheV9tYXApICsgZ2VvbV9sZWcoZGF0YSA9IHZhcl93YXlzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IHN0YXJ0TG9uLCB4ZW5kID0gZW5kTG9uLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHN0YXJ0TGF0LCB5ZW5kID0gZW5kTGF0LCBjb2xvciA9IHJvdXRlKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgYWxwaGEgPSAwLjcsIHNpemUgPSAyKQpgYGAKIyMjIyAxLjIgRXh0cmFjdCB3aXRoIG9zbWFyIFIKVGhlcmUgYXJlIHNldmVyYWwgd2F5cyB0byBleHRyYWN0IGdlb2RhdGEuIE9uZSBvZiB0aGVtIGlzIHRvIGRvIHRoaXMgd2l0aCB0aGlzIFIgY29kZSBjZWxscy4KClRoaXMgc2V0IG9mIGNvbW1hbmRzIGFsbG93cyB1cyB0byB1cGxvYWQgdGhlIGRhdGEgdXNpbmcgdGhlIGNvb3JkaW5hdGVzLgpgYGB7cn0Kc3JjIDwtIG9zbXNvdXJjZV9hcGkoKQpiaWdib3ggPC0gY2VudGVyX2Jib3goNTUuMjcwOCwgMjUuMjA0OCwgNjAwMCwgNjAwMCkKYmR1YmFpIDwtIGdldF9vc20oYmlnYm94LCBzb3VyY2UgPSBzcmMpCmBgYApgYGB7cn0Kc3RyKGJkdWJhaSkKYGBgCk5vZGUgdGFnczoKYGBge3J9Cm5vZGVfdGFncyA8LSBzb3J0KHVuaXF1ZShiZHViYWkkbm9kZXMkdGFncyRrKSkKcHJpbnQobm9kZV90YWdzKQpgYGAKV2F5IHRhZ3M6CmBgYHtyfQp3YXlfdGFncyA8LSBzb3J0KHVuaXF1ZShiZHViYWkkd2F5cyR0YWdzJGspKQpwcmludCh3YXlfdGFncykKYGBgClVzZXJzOgpgYGB7cn0KdXNlcnMgPC0gc29ydCh1bmlxdWUoYmR1YmFpJG5vZGVzJGF0dHJzJHVzZXIpKQpwcmludChoZWFkKHVzZXJzLCAxMikpCmBgYAojIyMjIDEuMyBQbG90dGluZyB3aXRoIG9zbWFyIFIKYGBge3IgZmlnLndpZHRoPTksIGZpZy5oZWlnaHQ9OSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KcGxvdChiZHViYWkpCmBgYApgYGB7cn0KdHMgPC0gZmluZChiZHViYWksIG5vZGUodGFncyh2ID09ICJ0cmFmZmljX3NpZ25hbHMiKSkpCnRzX2R1YmFpIDwtIHN1YnNldChiZHViYWksIG5vZGVfaWRzID0gdHMpCmJzIDwtIGZpbmQoYmR1YmFpLCBub2RlKHRhZ3ModiAlYWdyZXAlICJidXNzdG9wIikpKQpic19kdWJhaSA8LSBzdWJzZXQoYmR1YmFpLCBub2RlX2lkcyA9IGJzKQpodyA8LSBmaW5kKGJkdWJhaSwgd2F5KHRhZ3MoayA9PSAiaGlnaHdheSIpKSkKaHcgPC0gZmluZF9kb3duKGJkdWJhaSwgd2F5KGh3KSkKaHdfZHViYWkgPC0gc3Vic2V0KGJkdWJhaSwgaWRzID0gaHcpCnR1IDwtIGZpbmQoYmR1YmFpLCB3YXkodGFncyhrID09ICJ0dW5uZWwiKSkpCnR1IDwtIGZpbmRfZG93bihiZHViYWksIHdheSh0dSkpCnR1X2R1YmFpIDwtIHN1YnNldChiZHViYWksIGlkcyA9IHR1KQpgYGAKYGBge3IgZmlnLndpZHRoPTksIGZpZy5oZWlnaHQ9OSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KcGxvdF93YXlzKGh3X2R1YmFpLCBjb2wgPSAic3RlZWxibHVlIikKcGxvdF93YXlzKHR1X2R1YmFpLCBhZGQgPSBUUlVFLCBjb2wgPSAibWFnZW50YSIpCnBsb3Rfbm9kZXModHNfZHViYWksIGFkZCA9IFRSVUUsIGNvbCA9ICJyZWQiKQpwbG90X25vZGVzKGJzX2R1YmFpLCBhZGQgPSBUUlVFLCBjb2wgPSAiYmx1ZSIpCmBgYApgYGB7cn0KYmcgPC0gZmluZChiZHViYWksIHdheSh0YWdzKGsgPT0gImJ1aWxkaW5nIikpKQpiZyA8LSBmaW5kX2Rvd24oYmR1YmFpLCB3YXkoYmcpKQpiZ19kdWJhaSA8LSBzdWJzZXQoYmR1YmFpLCBpZHMgPSBiZykKYmdfcG9seSA8LSBhc19zcChiZ19kdWJhaSwgInBvbHlnb25zIikKYGBgCmBgYHtyIGZpZy53aWR0aD05LCBmaWcuaGVpZ2h0PTksIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CnNwcGxvdChiZ19wb2x5LCBjb2wucmVnaW9ucz1icmV3ZXIucGFsKDEyLCAiU2V0MyIpLCBjKCJ2ZXJzaW9uIikpCmBgYApgYGB7cn0KIyBidXMgPC0gZmluZChiZHViYWksIHJlbGF0aW9uKHRhZ3ModiA9PSAiYnVzIikpKQojIGJ1c19kdWJhaSA8LSBsYXBwbHkoYnVzLCBmdW5jdGlvbihpKSB7IGFzX3NwKGdldF9vc20ocmVsYXRpb24oaSksIGZ1bGwgPSBUUlVFKSwgImxpbmVzIikgfSkKYnNfcG9pbnRzIDwtIGFzX3NwKGJzX2R1YmFpLCAicG9pbnRzIikKaHdfbGluZSA8LSBhc19zcChod19kdWJhaSwgImxpbmVzIikKYGBgCmBgYHtyIGZpZy53aWR0aD05LCBmaWcuaGVpZ2h0PTksIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiMgZm9yICggaSBpbiBzZXEoYWxvbmcgPSBidXNfZHViYWkpICkgeyBwbG90KGJ1c1tbaV1dLCBhZGQgPSBUUlVFLCBjb2wgPSAiYmx1ZSIpIH0KcGxvdChiZ19wb2x5LCBjb2wgPSAibGlnaHRzdGVlbGJsdWUiKQpwbG90KGh3X2xpbmUsIGFkZCA9IFRSVUUsIGNvbCA9ICJibHVlIikKcGxvdChic19wb2ludHMsIGFkZCA9IFRSVUUsIGNvbCA9ICJyZWQiKQpgYGAKIyMjIyAxLjQuIEV4dHJhY3QgZnJvbSBPcGVuU3RyZWV0TWFwcy5vcmcuIApBbm90aGVyIHBvc3NpYmxlIHdheSBpcyBleHRyYWN0aW5nIGRhdGEgZmlsZXMgaW4gbWFueSBkaWZmZXJlbnQgZm9ybWF0cyBmcm9tIHRoZSB3ZWJzaXRlOgpodHRwczovL21hcHplbi5jb20vZGF0YS9tZXRyby1leHRyYWN0cy9tZXRyby9kdWJhaV9hYnUtZGhhYmkvIC4KVGhlIGZpbGVzIGR1YmFpX2FidS1kaGFiaS5vc20sIGR1YmFpX2FidS1kaGFiaV9idWlsZGluZ3MuZ2VvanNvbiwgZXRjLiB3ZXJlIGRvd25sb2FkZWQuClRoZSBkYXRhIGZyb20gdGhlIGZvcm1hdCBvc20gb2YgdGhlIGZpbGUgd2VyZSBleHRyYWN0ZWQgaW4gZm9ybWF0cyBjc3YgYW5kIGpzb24gdXNpbmcgc3BlY2lhbGx5IGRlc2lnbmVkIGZ1bmN0aW9ucyBpbiB0aGUgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgcHl0aG9uLgoKU2l6ZSBvZiB0aGUgZG93bmxvYWRlZCBvc20sIGpzb24gYW5kIGNzdiBmaWxlLgpgYGB7cn0KcHJpbnQoZmlsZS5zaXplKCIvVXNlcnMvb2xnYWJlbGl0c2theWEvbGFyZ2UtcmVwby9kdWJhaV9hYnUtZGhhYmkub3NtIikpCnByaW50KGZpbGUuc2l6ZSgiL1VzZXJzL29sZ2FiZWxpdHNrYXlhL2xhcmdlLXJlcG8vZHViYWlfYWJ1LWRoYWJpLm9zbS5qc29uIikpCmBgYApgYGB7cn0KcHJpbnQoZmlsZS5zaXplKCIvVXNlcnMvb2xnYWJlbGl0c2theWEvbGFyZ2UtcmVwby9ub2Rlcy5jc3YiKSkKcHJpbnQoZmlsZS5zaXplKCIvVXNlcnMvb2xnYWJlbGl0c2theWEvbGFyZ2UtcmVwby9ub2Rlc190YWdzLmNzdiIpKQpwcmludChmaWxlLnNpemUoIi9Vc2Vycy9vbGdhYmVsaXRza2F5YS9sYXJnZS1yZXBvL3dheXMuY3N2IikpCnByaW50KGZpbGUuc2l6ZSgiL1VzZXJzL29sZ2FiZWxpdHNrYXlhL2xhcmdlLXJlcG8vd2F5c190YWdzLmNzdiIpKQpwcmludChmaWxlLnNpemUoIi9Vc2Vycy9vbGdhYmVsaXRza2F5YS9sYXJnZS1yZXBvL3dheXNfbm9kZXMuY3N2IikpCmBgYAojIyMgMi4gQ1NWICYgU1FMClRoZSBkaXNwbGF5ZWQgbGluZXMgb2YgY29kZSByZXByZXNlbnQgdGhlIHByb2Nlc3Mgb2YgcmVjb3JkaW5nIGluZm9ybWF0aW9uIG9mIHRoZSBDU1YgZmlsZXMgdG8gdGhlIFNRTCBkYXRhYmFzZS4KYGBge3J9CnNxbGl0ZSA8LSBkYkRyaXZlcigiU1FMaXRlIikKZHViYWlfYWJ1X2RoYWJpIDwtIGRiQ29ubmVjdChzcWxpdGUsImR1YmFpX2FidV9kaGFiaS5zcWxpdGUzIikKYGBgCgpgYGB7cn0Kbm9kZXMgPC0gcmVhZC5jc3YoJy9Vc2Vycy9vbGdhYmVsaXRza2F5YS9sYXJnZS1yZXBvL25vZGVzLmNzdicpCm5vZGVzX3RhZ3MgPC0gcmVhZC5jc3YoJy9Vc2Vycy9vbGdhYmVsaXRza2F5YS9sYXJnZS1yZXBvL25vZGVzX3RhZ3MuY3N2JykKd2F5cyA8LSByZWFkLmNzdignL1VzZXJzL29sZ2FiZWxpdHNrYXlhL2xhcmdlLXJlcG8vd2F5cy5jc3YnKQp3YXlzX3RhZ3MgPC0gcmVhZC5jc3YoJy9Vc2Vycy9vbGdhYmVsaXRza2F5YS9sYXJnZS1yZXBvL3dheXNfdGFncy5jc3YnKQp3YXlzX25vZGVzIDwtIHJlYWQuY3N2KCcvVXNlcnMvb2xnYWJlbGl0c2theWEvbGFyZ2UtcmVwby93YXlzX25vZGVzLmNzdicpCmBgYAoKYGBge3J9CmRiV3JpdGVUYWJsZShjb25uID0gZHViYWlfYWJ1X2RoYWJpLCBuYW1lID0gJ25vZGVzJywgdmFsdWUgPSBub2Rlcywgcm93Lm5hbWVzID0gRkFMU0UpCmRiV3JpdGVUYWJsZShjb25uID0gZHViYWlfYWJ1X2RoYWJpLCBuYW1lID0gJ25vZGVzX3RhZ3MnLCB2YWx1ZSA9IG5vZGVzX3RhZ3MsIHJvdy5uYW1lcyA9IEZBTFNFKQpkYldyaXRlVGFibGUoY29ubiA9IGR1YmFpX2FidV9kaGFiaSwgbmFtZSA9ICd3YXlzJywgdmFsdWUgPSB3YXlzLCByb3cubmFtZXMgPSBGQUxTRSkKZGJXcml0ZVRhYmxlKGNvbm4gPSBkdWJhaV9hYnVfZGhhYmksIG5hbWUgPSAnd2F5c190YWdzJywgdmFsdWUgPSB3YXlzX3RhZ3MsIHJvdy5uYW1lcyA9IEZBTFNFKQpkYldyaXRlVGFibGUoY29ubiA9IGR1YmFpX2FidV9kaGFiaSwgbmFtZSA9ICd3YXlzX25vZGVzJywgdmFsdWUgPSB3YXlzX25vZGVzLCByb3cubmFtZXMgPSBGQUxTRSkKYGBgCldpdGggdGhlIGhlbHAgb2Ygc2ltcGxlIG1hbmlwdWxhdGlvbnMgaW4gdGhlIGRhdGFiYXNlLCB0aGUgdXNlciBjYW4gcGVyZm9ybSBhIHNlbGVjdGlvbiBvZiBpbnRlcmVzdGluZyBpbmZvcm1hdGlvbi4gCgpUaGUgZXhhbXBsZXMgb2Ygbm9kZXMgYW5kIHdheXM6CmBgYHtyIG1lc3NhZ2U9RkFMU0V9CmZvcm1hdHRhYmxlKHNxbGRmKCJzZWxlY3QgKiBmcm9tIG5vZGVzIGxpbWl0IDMiLCBkYm5hbWUgPSAiZHViYWlfYWJ1X2RoYWJpIikpCmBgYApgYGB7ciBtZXNzYWdlPUZBTFNFfQpmb3JtYXR0YWJsZShzcWxkZigic2VsZWN0ICogZnJvbSB3YXlzIGxpbWl0IDMiLCBkYm5hbWUgPSAiZHViYWlfYWJ1X2RoYWJpIikpCmBgYApXZSBjYW4gZmluZCB0aGUgbnVtYmVyIG9mIG5vZGVzIGFuZCB3YXlzIGFzIHdlbGwuCmBgYHtyIG1lc3NhZ2U9RkFMU0V9CmZvcm1hdHRhYmxlKHNxbGRmKCJTRUxFQ1QgQ09VTlQoKikgRlJPTSBub2RlczsiKSkKYGBgCmBgYHtyIG1lc3NhZ2U9RkFMU0V9CmZvcm1hdHRhYmxlKHNxbGRmKCJTRUxFQ1QgQ09VTlQoKikgRlJPTSB3YXlzOyIpKQpgYGAKVGhlIG51bWJlciBvZiB1c2VyczoKYGBge3IgbWVzc2FnZT1GQUxTRX0KZm9ybWF0dGFibGUoc3FsZGYoIlNFTEVDVCBDT1VOVChESVNUSU5DVChlLnVpZCkpIEZST00gXAogICAgICAgICAgKFNFTEVDVCB1aWQgRlJPTSBub2RlcyBVTklPTiBBTEwgU0VMRUNUIHVpZCBGUk9NIHdheXMpIGU7IikpCmBgYApUaGUgZGF0YWJhc2UgYWxsb3dzIHRvIGV2YWx1YXRlIHRoZSBjb250cmlidXRpb24gb2YgZWFjaCBpbmRpdmlkdWFsIHVzZXIgaW4gbWFwIGVkaXRpbmcuCgpMZXQgdXMgbGlzdCB0aGUgdGhyZWUgbW9zdCBhY3RpdmUgZWRpdG9ycyBvZiB0aGlzIG1hcCBzZWN0aW9uOgpgYGB7cn0KZm9ybWF0dGFibGUoc3FsZGYoIlNFTEVDVCBlLnVzZXIsIENPVU5UKCopIGFzIG51bSBcCiAgICAgICAgICAgRlJPTSAoU0VMRUNUIHVzZXIgRlJPTSBub2RlcyBVTklPTiBBTEwgU0VMRUNUIHVzZXIgRlJPTSB3YXlzKSBlIFwKICAgICAgICAgICBHUk9VUCBCWSBlLnVzZXIgXAogICAgICAgICAgIE9SREVSIEJZIG51bSBERVNDIFwKICAgICAgICAgICBMSU1JVCAzOyIpKQpgYGAKQSBsaXN0IG9mIHRoZSAzIG1vc3QgY29tbW9uIHR5cGVzIG9mIHBsYWNlczoKYGBge3J9CmZvcm1hdHRhYmxlKHNxbGRmKCJTRUxFQ1QgdmFsdWUsIENPVU5UKCopIGFzIG51bSBcCiAgICAgICAgICAgIEZST00gbm9kZXNfdGFncyBcCiAgICAgICAgICAgIFdIRVJFIGtleT0ncGxhY2UnIFwKICAgICAgICAgICAgR1JPVVAgQlkgdmFsdWUgXAogICAgICAgICAgICBPUkRFUiBCWSBudW0gREVTQyBcCiAgICAgICAgICAgIExJTUlUIDM7IikpCmBgYApBIGxpc3Qgb2YgdGhlIDEwIG1vc3QgY29tbW9uIHR5cGVzIG9mIGJ1aWxkaW5nczoKYGBge3J9CmZvcm1hdHRhYmxlKHNxbGRmKCJTRUxFQ1QgdmFsdWUsIENPVU5UKCopIGFzIG51bSBcCiAgICAgICAgICAgIEZST00gbm9kZXNfdGFncyBcCiAgICAgICAgICAgIFdIRVJFIGtleT0nYnVpbGRpbmcnIFwKICAgICAgICAgICAgR1JPVVAgQlkgdmFsdWUgXAogICAgICAgICAgICBPUkRFUiBCWSBudW0gREVTQyBcCiAgICAgICAgICAgIExJTUlUIDEwOyIpKQpgYGAKQSBsaXN0IG9mIHRoZSAyMCBtb3N0IGNvbW1vbiBzdHJlZXRzOgpgYGB7cn0KZm9ybWF0dGFibGUoc3FsZGYoIlNFTEVDVCB2YWx1ZSwgQ09VTlQoKikgYXMgbnVtIFwKICAgICAgICAgICAgRlJPTSBub2Rlc190YWdzIFwKICAgICAgICAgICBXSEVSRSBrZXk9J3N0cmVldCcgXAogICAgICAgICAgIEdST1VQIEJZIHZhbHVlIFwKICAgICAgICAgICBPUkRFUiBCWSBudW0gREVTQyBcCiAgICAgICAgICAgTElNSVQgMjA7IikpCmBgYApgYGB7cn0KZGJEaXNjb25uZWN0KGR1YmFpX2FidV9kaGFiaSkKYGBgCiMjIyAzLiBKU09OICYgTW9uZ29EQgpXaXRoIHZlcnkgc2ltaWxhciBtYW5pcHVsYXRpb25zIHdlIGNhbiBpbXBvcnQgdGhlIGRhdGEgZnJvbSBKU09OIGZpbGVzIGludG8gTW9uZ29EQi4KClN0YXJ0IHdpdGggcnVubmluZyAnbW9uZ29kJyBmcm9tIHRoZSB0ZXJtaW5hbCwgZW5kIHdpdGggJ0N0cmwrQycuCmBgYHtyfQptIDwtIG1vbmdvKCJvcGVuc3RyZWV0bWFwIiwgdmVyYm9zZSA9IEZBTFNFKQpgYGAKYGBge3J9CiMgc3RyZWFtX2luKGZpbGUoImR1YmFpX2FidS1kaGFiaS5vc20uanNvbiIpLCBoYW5kbGVyID0gZnVuY3Rpb24oZGYpe20kaW5zZXJ0KGRmKX0pCmBgYApUaGUgbnVtYmVyIG9mIGRvY3VtZW50czoKYGBge3J9Cm0kY291bnQoKQpgYGAKVGhlIHRocmVlIG1vc3QgYWN0aXZlIGVkaXRvcnMgb2YgdGhpcyBtYXAgc2VjdGlvbjoKYGBge3J9CnRvcF91c2VycyA8LSBtJGFnZ3JlZ2F0ZSgnWwp7ICIkZ3JvdXAiIDogeyAiX2lkIiA6ICIkY3JlYXRlZC51c2VyIiwgImNvdW50IiA6IHsgIiRzdW0iIDogMX0gfSB9LCAKeyAiJHNvcnQiIDogeyAiY291bnQiIDogLTF9IH0sIHsgIiRsaW1pdCIgOiAzIH0gCl0nKQpmb3JtYXR0YWJsZSh0b3BfdXNlcnMpCmBgYApUaGUgbnVtYmVyIG9mIHVzZXJzIHdpdGggb25lIG5vdGUgYW5kIHRoZSBsaXN0IG9mIDEwIHVzZXJzIHdpdGggb25seSBvbmUgbm90ZToKYGBge3J9Cm51bWJlcl9vb251IDwtIG0kYWdncmVnYXRlKCdbCnsgIiRncm91cCIgOiB7ICJfaWQiIDogIiRjcmVhdGVkLnVzZXIiLCAiY291bnQiIDogeyAiJHN1bSIgOiAxfSB9IH0sIAp7ICIkc29ydCIgOiB7ICJjb3VudCIgOiAxfSB9LCB7ICIkbGltaXQiIDogMTAgfSAKXScpCmZvcm1hdHRhYmxlKG51bWJlcl9vb251KQpgYGAKYGBge3J9CnRlbl9vb251IDwtIG0kYWdncmVnYXRlKCdbCnsgIiRncm91cCIgOiB7ICJfaWQiIDogIiRjcmVhdGVkLnVzZXIiLCAiY291bnQiIDogeyAiJHN1bSIgOiAxfSB9IH0sIAp7ICIkc29ydCIgOiB7ICJjb3VudCIgOiAxfSB9LCB7ICIkbGltaXQiIDogMTAgfSAKXScpCmZvcm1hdHRhYmxlKHRlbl9vb251KQpgYGAKQSBsaXN0IG9mIDMgbW9zdCBjb21tb24gcGxhY2VzOgpgYGB7cn0KcGxhY2VzIDwtIG0kYWdncmVnYXRlKCdbCnsgIiRtYXRjaCIgOiB7ICJhZGRyZXNzLnBsYWNlIiA6IHsgIiRleGlzdHMiIDogMX0gfSB9LCAKeyAiJGdyb3VwIiA6IHsgIl9pZCIgOiAiJGFkZHJlc3MucGxhY2UiLCAiY291bnQiIDogeyAiJHN1bSIgOiAxfSB9IH0sICAKeyAiJHNvcnQiIDogeyAiY291bnQiIDogLTF9fSwgeyIkbGltaXQiOjN9Cl0nKQpmb3JtYXR0YWJsZShwbGFjZXMpCmBgYApBIGxpc3Qgb2YgMTAgbW9zdCBjb21tb24gdHlwZXMgb2YgYnVpbGRpbmdzOgpgYGB7cn0KYnVpbGRpbmdzIDwtIG0kYWdncmVnYXRlKCdbCnsgIiRtYXRjaCI6IHsgImJ1aWxkaW5nIjogeyAiJGV4aXN0cyI6IDF9fX0sIAp7ICIkZ3JvdXAiOiB7ICJfaWQiOiAiJGJ1aWxkaW5nIiwgImNvdW50IjogeyAiJHN1bSI6IDF9fX0sIAp7ICIkc29ydCI6IHsgImNvdW50IjogLTF9fSwgeyIkbGltaXQiOiAxMH0KXScpCmZvcm1hdHRhYmxlKGJ1aWxkaW5ncykKYGBgCkEgbGlzdCBvZiAxMCBtb3N0IGNvbW1vbiBmYWNpbGl0aWVzOgpgYGB7cn0KZmFjaWxpdGllcyA8LSBtJGFnZ3JlZ2F0ZSgnWwp7ICIkbWF0Y2giOiB7ICJhbWVuaXR5IjogeyAiJGV4aXN0cyI6IDF9fX0sIAp7ICIkZ3JvdXAiOiB7ICJfaWQiOiAiJGFtZW5pdHkiLCAiY291bnQiOiB7ICIkc3VtIjogMX19fSwKeyAiJHNvcnQiOiB7ICJjb3VudCI6IC0xfX0sIHsgIiRsaW1pdCI6IDEwfQpdJykKZm9ybWF0dGFibGUoZmFjaWxpdGllcykKYGBgCkEgbGlzdCBvZiAzIG1vc3QgY29tbW9uIHppcGNvZGVzOgpgYGB7cn0KcG9zdGNvZGVzIDwtIG0kYWdncmVnYXRlKCdbIAp7ICIkbWF0Y2giIDogeyAiYWRkcmVzcy5wb3N0Y29kZSIgOiB7ICIkZXhpc3RzIiA6IDF9IH0gfSwgCnsgIiRncm91cCIgOiB7ICJfaWQiIDogIiRhZGRyZXNzLnBvc3Rjb2RlIiwgImNvdW50IiA6IHsgIiRzdW0iIDogMX0gfSB9LCAgCnsgIiRzb3J0IiA6IHsgImNvdW50IiA6IC0xfX0sIHsiJGxpbWl0IjogM30KXScpCmZvcm1hdHRhYmxlKHBvc3Rjb2RlcykKYGBgCkNvdW50aW5nIHppcGNvZGVzIHdpdGggb25lIGRvY3VtZW50OgpgYGB7cn0KcG9zdGNvZGVzX29kIDwtIG0kYWdncmVnYXRlKCdbIAp7ICIkZ3JvdXAiIDogeyJfaWQiIDogIiRhZGRyZXNzLnBvc3Rjb2RlIiwgImNvdW50IiA6IHsgIiRzdW0iIDogMX0gfSB9LAp7ICIkZ3JvdXAiIDogeyJfaWQiIDogIiRjb3VudCIsICJjb3VudCI6IHsgIiRzdW0iIDogMX0gfSB9LAp7ICIkc29ydCIgOiB7Il9pZCIgOiAxfSB9LCB7ICIkbGltaXQiIDogMX0gCl0nKQpmb3JtYXR0YWJsZShwb3N0Y29kZXNfb2QpCmBgYApFeGFtcGxlcyBvZiBzdGF0aXN0aWNzIGluZGljYXRvcnMgZm9yIHRoaXMgZGF0YXNldDoKYGBge3J9Cm0kaW5mbygpJHN0YXRzJG5zCmBgYApgYGB7cn0KbSRpbmZvKCkkc3RhdHMkc2l6ZQpgYGAKYGBge3J9Cm0kaW5mbygpJHN0YXRzJGF2Z09ialNpemUKYGBgCmBgYHtyfQptJGluZm8oKSRzdGF0cyRzdG9yYWdlU2l6ZQpgYGAKCiMjIyA0LiBQcm9ibGVtcyBhbmQgZXJyb3JzCgojIyMjIDQuMSAKT25lIG9mIHRoZSBtYWluIHByb2JsZW1zIG9mIHB1YmxpYyBtYXBzIC0gbm8gZHVwbGljYXRpb24gb2YgYWxsIHBsYWNlIG5hbWVzIGluIG90aGVyIGxhbmd1YWdlcy4gSWYgaXQgd2VyZSBwb3NzaWJsZSB0byBhdXRvbWF0ZSB0aGUgdHJhbnNsYXRpb24gcHJvY2VzcyBieSBpbmNyZWFzaW5nIGEgY29tbW9uIGRhdGFiYXNlIG9mIG1hcCBuYW1lcyBpbiBtYW55IGxhbmd1YWdlcywgaXQgd291bGQgc2F2ZSB1c2VycyBmcm9tIG1hbnkgZGlmZmljdWx0aWVzIGFuZCBtaXN0YWtlcy4KCiMjIyMgNC4yClRoZSBuZXh0IHByb2JsZW0gLSB0aGUgcHJlc2VuY2Ugb2YgYSBsYXJnZSBudW1iZXIgb2YgZGF0YWJhc2VzIChpbmNsdWRpbmcgbWFwcGluZykgb24gdGhlIHNhbWUgbWFwIG9iamVjdHMuIFNvbWUgaW50ZXJncmFwaCBwcm9jZWR1cmVzIG9mIGFscmVhZHkgYXZhaWxhYmxlIGRhdGEgd291bGQgcmVsaWV2ZSBhIGxvdCBvZiBwZW9wbGUgZnJvbSB1bm5lY2Vzc2FyeSB3b3JrLCBzYXZlIHRpbWUgYW5kIGVmZm9ydC4KCiMjIyMgNC4zCk9idmlvdXNseSwgdGhlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBudW1iZXIgb2YgYnVpbGRpbmdzIGFuZCB0aGVpciBwdXJwb3NlIGlzIGluY29tcGxldGUuIENvbXBsZXRlbmVzcyBvZiBwdWJsaWMgbWFwcyBjYW4gYmUgaW5jcmVhc2VkIGJ5IGJyaW5naW5nIGluIHRoZSBwcm9jZXNzIG9mIG1hcHBpbmcgbmV3IHVzZXJzLiBGb3IgdGhpcyBnb2FsIGVudGVyIHRoZSBpbmZvcm1hdGlvbiBzaG91bGQgYmUgYXMgc2ltcGxlIGFzIHBvc3NpYmxlOiBmb3IgZXhhbXBsZSwgYSBjaG9pY2Ugb2YgdGhlIGF2YWlsYWJsZSBvcHRpb25zIHdpdGggYXV0b21hdGljIGZpbGxpbmcgbWFueSBmaWVsZHMgZm9yIGxpbmtlZCBvcHRpb25zIChmb3IgZXhhbXBsZSwgbGlua2luZyB0aGUgbmFtZSBvZiB0aGUgc3RyZWV0IGFuZCB0aGUgYWRtaW5pc3RyYXRpdmUgYXJlYSBpbiB3aGljaCBpdCBpcyBsb2NhdGVkKS4KCiMjIyMgNC40IApUaGVyZSBhcmUgYSBudW1iZXIgb2YgbWlzdGFrZXMgYW5kIHR5cG9zIGFzIGluIGV2ZXJ5IHB1YmxpYyBkYXRhLiBGb3IgY29ycmVjdGlvbiB0aGVtIHdlbGwta25vd24gbWV0aG9kcyBjYW4gYmUgcHJvcG9zZWQ6IGF1dG9tYXRpYyBjb21wYXJpc29uIHdpdGggZXhpc3RpbmcgZGF0YSBhbmQgdmVyaWZpY2F0aW9uIGZvciBuZXcgZGF0YSBieSBvdGhlciB1c2Vycy4KCiMjIyMgNC41ClRoZSBsYWNrIG9mIGEgdW5pZm9ybSBwb3N0YWwgY29kZSBzeXN0ZW0gaW4gdGhpcyBjb25jcmV0ZSBkYXRhc2V0IGNvbXBsaWNhdGVzIHRoZWlyIGlkZW50aWZpY2F0aW9uIGFuZCB2ZXJpZmljYXRpb24uCgojIyMgNS4gRGF0YSBPdmVydmlldwoKIyMjIyA1LjEgRGVzY3JpcHRpb24gb2YgdGhlIGRhdGEgc3RydWN0dXJlOiAKMSkgbm9kZXMgLSAgcG9pbnRzIGluIHNwYWNlIHdpdGggYmFzaWMgY2hhcmFjdGVyaXN0aWNzIChsYXQsIGxvbmcsIGlkLCB0YWdzKTsKCjIpIHdheXMgLSBkZWZpbmluZyBsaW5lYXIgZmVhdHVyZXMgYW5kIGFyZWEgYm91bmRhcmllcyAoYW4gb3JkZXJlZCBsaXN0IG9mIG5vZGVzKTsKCjMpIHJlbGF0aW9ucyAtIHRhZ3MgYW5kIGFsc28gYW4gb3JkZXJlZCBsaXN0IG9mIG5vZGVzLCB3YXlzIGFuZC9vciByZWxhdGlvbnMgYXMgbWVtYmVycyB3aGljaCBpcyB1c2VkIHRvIGRlZmluZSBsb2dpY2FsIG9yIGdlb2dyYXBoaWMgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIG90aGVyIGVsZW1lbnRzLgoKIyMjIyA1LjIgSW5kaWNhdG9ycy4KMSkgU2l6ZSBvZiB0aGUgLm9zbSBmaWxlOiAzOTQsNCBNQi4KMikgU2l6ZSBvZiB0aGUgLm9zbSBzYW1wbGUgZmlsZSA6IDMsOSBNQi4KMykgTm9kZXM6IDE4OTAxNzguCjQpIFdheXM6IDIzNDMyNy4KNSkgUmVsYXRpb25zOiAyODIwLgo2KSBUYWdzOiA1MDMwMjcuCjcpIFVzZXJzOiAxODk1LgoKIyMjIyA1LjMgU1FMICYgTW9uZ29EQgpXaXRoIHRoZSBoZWxwIG9mIGEgc3BlY2lmaWMgc2V0IG9mIGNvbW1hbmRzIHdlIGNhbiBwZXJmb3JtIGEgc3RhdGlzdGljYWwgZGVzY3JpcHRpb24gb2YgdGhlIGRhdGEgY29sbGVjdGlvbnMgYW5kIHRoZSBkYXRhYmFzZS4KCiMjIyA2LiBDb25jbHVzaW9uCkkgdGhpbmsgdGhpcyBwcm9qZWN0IGlzIGVkdWNhdGlvbmFsIGZvciBtZS4gSSBiZWxpZXZlIHRoYXQgb25lIG9mIHRoZSBtYWluIHRhc2tzIGluIHRoaXMgY2FzZSB3YXMgdG8gc3R1ZHkgdGhlIG1ldGhvZHMgb2YgZXh0cmFjdGlvbiBhbmQgcmVzZWFyY2hpbmcgb2YgbWFwIGRhdGEgaW4gb3BlbiBhY2Nlc3MuIEZvciBleGFtcGxlLCBJIHVzZWQgYSBzeXN0ZW1hdGljIHNhbXBsZSBvZiBlbGVtZW50cyBmcm9tIHRoZSBvcmlnaW5hbCAub3NtIGZpbGUgZm9yIHRyeWluZyBmdW5jdGlvbnMgb2YgcHJvY2Vzc2luZyBiZWZvcmUgYXBwbHlpbmcgdGhlbSB0byB0aGUgd2hvbGUgZGF0YXNldC4gQXMgYSByZXN1bHQgSSBoYXZlIHNvbWUgbmV3IHVzZWZ1bCBza2lsbHMgaW4gcGFyc2luZywgcHJvY2Vzc2luZywgc3RvcmluZywgYWdncmVnYXRpbmcgYW5kIGFwcGx5aW5nIHRoZSBkYXRhLgoKSW4gdGhlIHJlc2VhcmNoIEkgaGF2ZSByZWFkIHRocm91Z2ggcXVpdGUgYSBsb3Qgb2YgcHJvamVjdHMgb2Ygb3RoZXIgc3R1ZGVudHMgb24gdGhpcyB0b3BpYy4gQWZ0ZXIgbXkgb3duIHJlc2VhcmNoIGFuZCByZXZpZXcgdGhlIHJlc3VsdHMgb2Ygb3RoZXIgYXV0aG9ycyBJIGhhdmUgZm9ybWVkIGEgZGVmaW5pdGUgb3BpbmlvbiBhYm91dCB0aGUgaWRlYXMgaW4gT3BlblN0cmVldE1hcC4KClRoaXMgd2Vic2l0ZSBjYW4gYmUgdmlld2VkIGFzIGEgdGVzdGluZyBncm91bmQgb2YgaW50ZXJhY3Rpb24gb2YgYSBsYXJnZSBudW1iZXIgb2YgcGVvcGxlIChuY2x1ZGluZyBub24tcHJvZmVzc2lvbmFscykgdG8gY3JlYXRlIGEgdW5pZmllZCBpbmZvcm1hdGlvbiBzcGFjZS4gVGhlIHByb3NwZWN0cyBvZiBzdWNoIGNvb3BlcmF0aW9uIGNhbiBub3QgYmUgb3ZlcmVtcGhhc2l6ZWQuIFRoZSBzdWNjZXNzIG9mIHRoZSBwcm9qZWN0IHdpbGwgYWxsb3cgdG8gaW1wbGVtZW50IHRoZSBhbWJpdGlvdXMgcGxhbnMgaW4gdGhlIGZpZWxkIG9mIGF2YWlsYWJsZSBpbmZvcm1hdGlvbiB0ZWNobm9sb2dpZXMsIHRoZSBjcmVhdGlvbiBvZiB2aXJ0dWFsIHJlYWxpdHkgYW5kIG1hbnkgb3RoZXIgYXJlYXMuCgpJbmNyZWFzaW5nIG9mIHRoZSBudW1iZXIgb2YgdXNlcnMgbGVhZHMgdG8gbWFueSBwb3NpdGl2ZSBlZmZlY3RzIGluIHRoaXMga2luZCBvZiBwcm9qZWN0czoKCjEpIGEgcmFwaWQgaW1wcm92ZW1lbnQgaW4gdGhlIGFjY3VyYWN5LCBjb21wbGV0ZW5lc3MgYW5kIHRpbWVsaW5lc3Mgb2YgaW5mb3JtYXRpb247CgoyKSBhcHByb3hpbWF0aW9uIG9mIHRoZSBpbmZvcm1hdGlvbiBzcGFjZSB0byB0aGUgcmVhbGl0eSAsIHRoZSBvYmplY3Rpdml0eSBvZiB0aGUgZGF0YSBldmFsdWF0aW9uOwoKMykgcmVkdWNlIHRoZSBlZmZvcnQgZm9yIGRhdGEgY2xlYW5zaW5nIG9uIGVycm9uZW91cyBkZXRhaWxzLgoKSWRlYXMgZm9yIGltcHJvdmluZyB0aGUgcHJvamVjdCBPcGVuU3RyZWV0TWFwIGFyZSBzaW1wbGUgYW5kIG5hdHVyYWwuCgpJbmNyZWFzaW5nIHRoZSBudW1iZXIgb2YgdXNlcnMgY2FuIGJlIGFjaGlldmVkIGJ5IGFkZGl0aW9uYWwgb3B0aW9ucyBsaWtlIG1hcmtzIG9mIHRoZSByYXRpbmcgZXZhbHVhdGlvbiAoZWcsIHRoZSBiZXN0IHJlc3RhdXJhbnQgb3IgdGhlIG1vc3QgY29udmVuaWVudCBwYXJraW5nKS4KClRoZSBwb3B1bGFyaXR5IG9mIHRoZSBwcm9qZWN0IG1heSBiZSBtb3JlIGR1ZSB0byB0aGUgdGVtcG9yYXJ5IHBvcC11cCBtZXNzYWdlcyBvZiB1c2VycyAocGxhY2VtZW50IGlzIG5vdCBtb3JlIHRoYW4gMS0zIGhvdXJzKSB3aXRoIGFjdHVhbCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZ2VvZ3JhcGhpYyBsb2NhdGlvbiAoZWcsIHRoZSBwcmVzZW5jZSBvZiB0cmFmZmljIGphbXMpLgoKIyMjIDcuIFVzZWZ1bCBsaW5rcwoKaHR0cHM6Ly93aWtpLm9wZW5zdHJlZXRtYXAub3JnL3dpa2kvT1NNX1hNTApodHRwczovL3d3dy5kYXRhY2FtcC5jb20vY29tbXVuaXR5L3R1dG9yaWFscy9yLWRhdGEtaW1wb3J0LXR1dG9yaWFsI2dzLmpVRTJVSHcKaHR0cDovL3d3dzIudWFlbS5teC9yLW1pcnJvci93ZWIvcGFja2FnZXMvb3NtYXIvb3NtYXIucGRmCmh0dHBzOi8vd3d3LnJlc2VhcmNoZ2F0ZS5uZXQvcHVibGljYXRpb24vMjc0NzQwNjQ1X0hhcm5lc3Npbmdfb3Blbl9zdHJlZXRfbWFwX2RhdGFfd2l0aF9SX2FuZF9RR0lTCmh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9tb25nb2xpdGUvdmlnbmV0dGVzL2ludHJvLmh0bWwKaHR0cHM6Ly9qb3VybmFsLnItcHJvamVjdC5vcmcvYXJjaGl2ZS8yMDEzLTEvZXVnc3Rlci1zY2hsZXNpbmdlci5wZGYKaHR0cDovL3d3dy5qb3lvZmRhdGEuZGUvYmxvZy9tb25nb2RiLXN0YXRlLW9mLXRoZS1yLXJtb25nb2RiLwpodHRwczovL2VkemVyLmdpdGh1Yi5pby9zcC8KaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2dnbWFwL2dnbWFwLnBkZgpodHRwczovL21lZGlhLnJlYWR0aGVkb2NzLm9yZy9wZGYvanVweXRlci1ub3RlYm9vay9sYXRlc3QvanVweXRlci1ub3RlYm9vay5wZGYKaHR0cHM6Ly9qb3VybmFsLnItcHJvamVjdC5vcmcvYXJjaGl2ZS8yMDEzLTEva2FobGUtd2lja2hhbS5wZGYKaHR0cHM6Ly93d3cuci1ibG9nZ2Vycy5jb20vci1hbmQtbW9uZ29kYi8KaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL21vbmdvbGl0ZS9tb25nb2xpdGUucGRmCmh0dHBzOi8vd3d3LnItYmxvZ2dlcnMuY29tL3ItYW5kLXNxbGl0ZS1wYXJ0LTEvCmh0dHBzOi8vd3d3LmRhdGFjYW1wLmNvbS9jb21tdW5pdHkvdHV0b3JpYWxzL2ltcG9ydGluZy1kYXRhLXItcGFydC10d28jZ3MuX1BFSTZpWQpodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvcmlvL3ZpZ25ldHRlcy9yaW8uaHRtbApodHRwOi8vZmxvdnYuZ2l0aHViLmlvL0dhc19wcmljZS1NYXBwaW5nLwoKCgo=